/*********************************************************
 *   > File Name: led.c
 *   > Author: fly
 *   > Create Time: 2021-06-26  6/25  21:46:02 +0800
 *======================================================*/
typedef struct{
    unsigned int GPD0CON;
    unsigned int GPD0DAT;
    unsigned int GPD0PUD;
    unsigned int GPD0DRV;
    unsigned int GPD0CONPDN;
    unsigned int GPD0PUDPDN;
}gpd0;
#define GPD0 (*(volatile gpd0*)0xE02000A0) 

typedef struct{
    unsigned int GPJ0CON;
    unsigned int GPJ0DAT;
    unsigned int GPJ0PUD;
    unsigned int GPJ0DRV;
    unsigned int GPJ0CONPDN;
    unsigned int GPJ0PUDPDN;
}gpj0;
#define GPJ0 (*(volatile gpj0*)0xE0200240) 

void delay(volatile unsigned int i)
{
    while(i--);
}

unsigned int readl(unsigned int addr)
{
    return ( *((volatile unsigned int *)addr) );
}

void writel(unsigned int addr, unsigned int value)
{
    *((volatile unsigned int *)addr) = value;
}

void led_init(void)
{
    /* LED1 */
    GPJ0.GPJ0CON = (GPJ0.GPJ0CON & ~(0xf<<12)) | (0x1<<12);
    GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<3)) | (0x1<<3);

    /* LED2 */
    GPJ0.GPJ0CON = (GPJ0.GPJ0CON & ~(0xf<<16)) | (0x1<<16);
    GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<4)) | (0x1<<4);

    /* LED3 */
    GPJ0.GPJ0CON = (GPJ0.GPJ0CON & ~(0xf<<20)) | (0x1<<20);
    GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<5)) | (0x1<<5);

    /* LED4 */
    GPD0.GPD0CON = (GPD0.GPD0CON & ~(0xf<<4)) | (0x1<<4);
    GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<1)) | (0x1<<1);
}

void led_set_led1(unsigned int value)
{
    if (value){
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<3)) | (0x0<<3);//ON
    }else{
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<3)) | (0x1<<3);//OFF
    }
}

void led_set_led2(unsigned int value)
{
    if (value){
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<4)) | (0x0<<4);//ON
    }else{
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<4)) | (0x1<<4);//OFF
    }
}

void led_set_led3(unsigned int value)
{
    if (value){
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<5)) | (0x0<<5);//ON
    }else{
        GPJ0.GPJ0DAT = (GPJ0.GPJ0DAT & ~(0x1<<5)) | (0x1<<5);//OFF
    }
}

void led_set_led4(unsigned int value)
{
    if (value){
        GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<1)) | (0x0<<1);//ON
    }else{
        GPD0.GPD0DAT = (GPD0.GPD0DAT & ~(0x1<<1)) | (0x1<<1);//OFF
    }
}

void led_set_all_led(unsigned int value)
{
    if(value){
        led_set_led1(1);
        led_set_led2(1);
        led_set_led3(1);
        led_set_led4(1);
    }else{
        led_set_led1(0);
        led_set_led2(0);
        led_set_led3(0);
        led_set_led4(0);
    }
}

void tester_led(void)
{
    led_init();

    while(1){
        led_set_led1(1);
        delay(900000);
        led_set_led1(0);
        led_set_led2(1);
        delay(900000);
        led_set_led2(0); 
        led_set_led3(1);
        delay(900000);
        led_set_led3(0); 
        led_set_led4(1);
        delay(900000);
        led_set_all_led(1);
        delay(900000);
        led_set_all_led(0);
        delay(900000);
    }
}

void tester_breath_led(void)
{
    #define CYCLE       (3500)
    unsigned int pwm;
    led_init();

    while(1){
        /* LED灯渐渐变亮 */
        for(pwm = 1; pwm < CYCLE; pwm++)
        {
            led_set_led4(0), delay(CYCLE - pwm);
            led_set_led4(1), delay(pwm);  
        }
        led_set_led4(1), delay(pwm/5);
        /* LED灯渐渐熄灭 */
        for(pwm = 1; pwm < CYCLE; pwm++)
        {
            led_set_led4(1), delay(CYCLE - pwm);
            led_set_led4(0), delay(pwm);   
        }
        led_set_led4(0), delay(pwm);
    }
}

int main(int argc, char* argv[])
{
    tester_breath_led();

    return 0;
}
